import MediaApi from '@/api/media'
import { useCancelToken } from '@/utils/request'

// 给所有children都添加对应的新字段 --- prop
const everyAdd = function(arr, prop) {
  return arr.map(item => {
    let out = {}
    let children = []
    if (item.children && item.children instanceof Array && item.children.length > 0) {
      children = everyAdd(item.children, prop)
    }
    out = {
      ...item
    }
    out[prop] = true
    if (children.length > 0) out.children = children
    return out
  })
}

const state = {
  tagList: { // 标签列表
    done: false, // 是否请求过
    data: []
  },
  tagTree: { // 标签树
    done: false,
    data: []
  },
  dynamicTagTree: { // 动态标签树 用于创建下级元素选择标签
    data: []
  },
  menuTree: {
    mediaCenter: [{
      id: 0,
      name: '我的媒体',
      children: []
    }, {
      id: -1,
      name: '下级用户媒体',
      children: []
    }, {
      id: -2,
      name: '其他媒体',
      _isOther: true,
      children: []
    }],
    mediaAudit: [
    {
      id: -3,
      name: '全部',
      children: []
    },{
      id: 0,
      name: '我的媒体',
      children: []
    }, {
      id: -2,
      name: '其他媒体',
      _isOther: true,
      children: []
    }],
    mediaTemplate: [{
      id: 0,
      name: '我的模版',
      children: []
    }, {
      id: -1,
      name: '下级用户模版',
      children: []
    }, {
      id: -2,
      name: '其他模板',
      _isOther: true,
      children: []
    }],
    showMake: [{
      id: 0,
      name: '我的节目',
      children: []
    }, {
      id: -1,
      name: '下级用户节目',
      children: [],
      disable:true,
    }, {
      id: -2,
      name: '其他节目',
      _isOther: true,
      children: []
    }],
    showPublic: [{
      id: 0,
      groupScreen: -1,
      name: '所有分组编排',
      children: [],
      disabled: true
    }]
  },
  uploadList: [], // 媒体中心 媒体上传列表
  singleUploading: false, // 正在逐个上传
  isQuikUpload:false,
  needFetchingList: { // 是否需要重新获取当前列表数据的标识 --- 用于一些操作后 --- 比如媒体被模版或节目使用后，媒体需刷新来更新被使用字段
    media: false,
    template: false,
    program: false
  }
}

function copyState () {
  console.log('copyState------', state)
  return JSON.parse(JSON.stringify(state))
}

const mutations = {
  SET_NEED_FETCHING_LIST: (state, {pageName, value}) => {
    state.needFetchingList[pageName] = value
  },
  SET_TAG_LIST: (state, {data}) => {
    state.tagList = {
      done: true,
      data
    }
  },
  SET_TAG_TREE: (state, {data}) => {
    state.tagTree = {
      done: true,
      data
    }
  },
  SET_DYNAMIC_TAG_TREE: (state, {data}) => {
    state.dynamicTagTree = {
      data
    }
  },
  SET_MEDIA_CENTER_MENU: (state, {treeData, isSub, otherMediaTreeData}) => {
    if(treeData) {
      if (!isSub) {
        state.menuTree.mediaCenter[0].children = treeData
      } else {
        state.menuTree.mediaCenter[1].children = everyAdd(treeData, '_isSub')
      }
    } else {
      if(otherMediaTreeData) {
        state.menuTree.mediaCenter[2].children = everyAdd(otherMediaTreeData, '_isOther')
      }
    }
  },
  SET_MEDIA_AUDIT_MENU: (state, {treeData, isSub}) => {
    if(treeData) {
      if (!isSub) {
        state.menuTree.mediaAudit[1].children = treeData
      } 
      else {
        state.menuTree.mediaAudit[2].children = everyAdd(treeData, '_isSub')
      }
    }
  },
  SET_MEDIA_TEMPLATE_MENU: (state, {treeData, isSub, otherMediaTreeData}) => {
    if(treeData) {
      if (!isSub) {
        state.menuTree.mediaTemplate[0].children = treeData
      } else {
        state.menuTree.mediaTemplate[1].children = everyAdd(treeData, '_isSub')
      }
    } else {
      if(otherMediaTreeData) {
        state.menuTree.mediaTemplate[2].children = everyAdd(otherMediaTreeData, '_isOther')
      }
    }
  },
  SET_SHOW_MAKE_MENU: (state, {treeData, isSub, otherMediaTreeData}) => {
    if(treeData) {
      if (!isSub) {
        state.menuTree.showMake[0].children = treeData
      } else {
        state.menuTree.showMake[1].children = everyAdd(treeData, '_isSub')
      }
    } else {
      if(otherMediaTreeData) {
        state.menuTree.showMake[2].children = everyAdd(otherMediaTreeData, '_isOther')
      }
    }
  },
  SET_SHOW_PUBLIC_MENU: (state, treeData) => {
    if (!treeData) return
    state.menuTree.showPublic[0].children = treeData
  },
  SET_SINGLE_UPLOADING: (state, isUploading) => {
    state.singleUploading = isUploading
  },
  SET_UPLOAD_LIST: (state, fileList) => {
    state.uploadList = fileList.map(file => {
      const _file = {
        ...file
      }
      if (!file.file_status && file.file_status !== 0) _file.file_status = 'wating'
      if (!file.speed) _file.speed = ''
      if (!file.file_overTime) _file.file_overTime = ''
      return _file
    })
  },
  UPDATE_UPLOAD_LIST_FILE: (state, { file, props }) => {
    const _file = state.uploadList.find(f => f.uid === file.uid)
    if (!_file) return false
    for (const prop in props) {
      _file[prop] = props[prop]
    }
  },
  DELETE_UPLOAD_LIST_FILE: (state, { file }) => {
    const _fileIndex = state.uploadList.findIndex(f => f.uid === file.uid)
    if (_fileIndex < 0) return false
    const _file = state.uploadList[_fileIndex]
    const {file_status, cancelControl} = _file
    if (typeof file_status === 'number') {
      cancelControl && cancelControl.cancel()
    }
    state.uploadList.splice(_fileIndex, 1)
  },
  DELETE_UPLOAD_LIST_BY_FILESTATUS: (state, file_status) => {
    switch (file_status) {
      case 'fail':
      case 'success':
        state.uploadList = state.uploadList.filter(file => {
          const needRemove = file.file_status === file_status
          return !needRemove
        })
        break;
      default: // 默认删除所有的
        state.uploadList.forEach(file => {
          if (typeof file.file_status === 'number') { // 如果正在上传需要中断上传请求
            file.cancelControl && file.cancelControl.cancel()
          }
        });
        state.uploadList = []
        break;
    }
  },
  CHANGE_QUIKUPLOAD: (state, { key, value }) => {
    // eslint-disable-next-line no-prototype-builtins
    if (state.hasOwnProperty(key)) {
      state[key] = value
    }
  },
  INIT_STATE: (state) => {
    const _state = copyState()
    for (const prop in _state) {
      state[prop] = _state[prop]
    }
    console.log(state, '-----INIT_STATE')
  }
}

const actions = {
  resetState({commit}) {
    commit('INIT_STATE')
  },
  setNeedFetching({commit}, {change}) {
    console.log('----change', change)
    if (change instanceof Array) {
      change.forEach(c => {
        commit('SET_NEED_FETCHING_LIST', {pageName: c, value: true})
      })
    } else {
      commit('SET_NEED_FETCHING_LIST', {pageName: change, value: true})
    }
  },
  clearNeedFetcing({commit}, {change}) {
    commit('SET_NEED_FETCHING_LIST', {pageName: change, value: false})
  },
  async getTagList({ state, commit, dispatch }, {isForce} = {}) {
    if (state.tagList.done && !isForce) return
    dispatch('getTagTree', {isForce})
    try {
      const res = await MediaApi.getTag({})
      commit('SET_TAG_LIST', {data: res})
    } catch (error) {
      console.log('err', error)
    }
  },
  async getTagTree({ state, commit }, {isForce, ownerUserIds, _self} = {}) {
    if (state.tagTree.done && !isForce && !ownerUserIds && !_self) return
    try {
      let params = {}
      if (ownerUserIds && ownerUserIds.length > 0) params.ownerUserIds = ownerUserIds
      const res = await MediaApi.getTagTree(params)
      if (!ownerUserIds && !_self) {
        commit('SET_TAG_TREE', {data: res})
      }
      commit('SET_DYNAMIC_TAG_TREE', {data: res})
    } catch (error) {
      console.log('err', error)
    }
  },
  setMenuTree({ commit }, {type, treeData, otherMediaTreeData, isSub}) {
    switch (Number(type)) {
      case 1:
        commit('SET_MEDIA_CENTER_MENU', {treeData, isSub, otherMediaTreeData})
        break;
      case 2:
        commit('SET_MEDIA_TEMPLATE_MENU', {treeData, isSub, otherMediaTreeData})
        break;
      case 3:
        commit('SET_SHOW_MAKE_MENU', {treeData, isSub, otherMediaTreeData})
        break;
      case 4:
        commit('SET_SHOW_PUBLIC_MENU', treeData)
        break;
      case 5:
        commit('SET_MEDIA_AUDIT_MENU', {treeData, isSub})
        break
      default:
        break;
    }
  },
  setUploadList({ commit }, fileList) {
    commit('SET_UPLOAD_LIST', fileList)
  },
  mutiUpload({ state, dispatch }) {
    const fetchingNum = state.uploadList.filter(item => {
      return typeof item.file_status === 'number'
    }).length
    const maxUpNum = 10
    let canFetchNum = maxUpNum - fetchingNum
    for(let i = 0; i < state.uploadList.length; i++) {
      if (canFetchNum < 1) return false
      const file = state.uploadList[i]
      if (file.file_status === 'wating') {
        canFetchNum--
        dispatch('uploadFetch', { file })
      }
    }
  },
  singleUpload({ state, dispatch, commit }) {
    const fetchingNum = state.uploadList.filter(item => {
      return typeof item.file_status === 'number'
    }).length
    if (fetchingNum > 0) return // 有上传中的文件
    const file = state.uploadList.find(item => item.file_status === 'wating')
    if (!file) return commit('SET_SINGLE_UPLOADING', false)// 已没有等待上传的文件

    commit('SET_SINGLE_UPLOADING', true)
    dispatch('uploadFetch', {file, finalCb: () => {
      dispatch('singleUpload')
    }})
  },
  async uploadFetch({ commit }, {file, finalCb}) {
    const [cancelToken, cancelControl] = useCancelToken()
    const _file = file
    commit('UPDATE_UPLOAD_LIST_FILE', {file: _file, props: {cancelControl}})
    try {
      let params = {
        file: _file.raw,
        folderId: typeof _file.menu === 'string' ? Number(_file.menu) : 0, // typeof _file.menu === 'string' ? 0 : _file.menu,
        convert: _file.isConvert
      }
      if (_file.ownerUserId) params.ownerUserId = _file.ownerUserId
      const res = await MediaApi.upload(params, (p, s, over) => {
        commit('UPDATE_UPLOAD_LIST_FILE', {
          file: _file,
          props: {
            file_status: p,
            speed: s,
            file_overTime: over
          }
        })
      }, cancelToken)

      commit('UPDATE_UPLOAD_LIST_FILE', {
        file: _file,
        props: {
          file_status: !res ? 'fail' : 'success'
        }
      })
    } catch (error) {
      
      commit('UPDATE_UPLOAD_LIST_FILE', {
        file: _file,
        props: {
          file_status: 'fail'
        }
      })
      
    } finally {
      
      commit('UPDATE_UPLOAD_LIST_FILE', {
        file: _file,
        props: {
          speed: '',
          file_overTime: ''
        }
      })
      finalCb && finalCb()
     
    }
  },
  delUpload({commit}, {file, fileState}) {
    if (file) {
      commit('DELETE_UPLOAD_LIST_FILE', {file})
    } else {
      commit('DELETE_UPLOAD_LIST_BY_FILESTATUS', fileState)
    }
  },
  changeQuikUpload({ commit }, data) {
    commit('CHANGE_QUIKUPLOAD', data)
  },

  getScheduleXml({ commit }, params) {
    return new Promise(resolve => {
      MediaApi.getScheduleXml(params).then(res => {
        resolve(res)
      })
    })
  },
}

const getters = {
  menuTree: (state) => (type) => {
    switch (Number(type)) {
      case 1:
        return state.menuTree.mediaCenter
      case 2:
        return state.menuTree.mediaTemplate
      case 3:
        return state.menuTree.showMake
      case 4:
        return state.menuTree.showPublic
      case 5:
        return state.menuTree.mediaAudit
      default:
        return []
    }
  },
  needFetchingList: (state) => (change) => {
    return state.needFetchingList[change]
  },
  menuTreeNoOther: (state, getters) => (type) => {
    return getters.menuTree(type).filter(mt => mt.id !== -2)
  },
  tagList: (state) => {
    return state.tagList.data
  },
  tagTreeWithInner: (state) => { // 包含内置标签的树
    return state.tagTree.data.map(item => {
      if (!item.type) { // 内置标签 处理id为name本身
        return {
          ...item,
          children: item.children.map(i => ({name: i.name, id: `innerTag:${i.name}`}))
        }
      } else {
        return {
          ...item
        }
      }
    })
  },
  tagTree: (state) => { // 除去内置标签的树
    return state.tagTree.data.filter(item => item.type)
  },
  dynTagTreeWithInner: (state) => { // 包含内置标签的动态树
    return state.dynamicTagTree.data.map(item => {
      if (!item.type) { // 内置标签 处理id为name本身
        return {
          ...item,
          children: item.children.map(i => ({name: i.name, id: `innerTag:${i.name}`}))
        }
      } else {
        return {
          ...item
        }
      }
    })
  },
  dynTagTree: (state) => { // 除去内置标签的动态树
    return state.dynamicTagTree.data.filter(item => item.type)
  },
  
}

export default {
  namespaced: true,
  state: copyState(),
  mutations,
  actions,
  getters
}
